#include "list/list.h"
#include "memory/memory.h"
#include <string.h>

#define LIST_POOL_MAX_CNT 8  // 列表池容量

struct TListNodeTag
{
    void *item_arr_;

    struct TListNodeTag *prev_;
    struct TListNodeTag *next_;
};
typedef struct TListNodeTag TListNode;

struct TListTag
{
    TListNode list_head_;

    Bool  is_used_;

    Int32 item_cnt_;
};
typedef struct TListTag TList;

static TList list_pool_[LIST_POOL_MAX_CNT];

#define IsHandleValid(handle) (handle >= 0 && handle < LIST_POOL_MAX_CNT)
#define IsHandleUsed(handle) (list_pool_[handle].is_used_)


TList_handle TListCreate(void)
{
    TList_handle ret_handle = -1;

    for (Int32 idx = 0; idx < LIST_POOL_MAX_CNT; idx ++)
    {
        if (! list_pool_[idx].is_used_)
        {
            list_pool_[idx].item_cnt_ = 0;
            list_pool_[idx].list_head_.item_arr_ = NULL;
            list_pool_[idx].list_head_.prev_ = &list_pool_[idx].list_head_;
            list_pool_[idx].list_head_.next_ = &list_pool_[idx].list_head_;

            list_pool_[idx].is_used_  = True;

            ret_handle = idx;

            break;
        }
    }

    return ret_handle;
}

void TListDestroy(TList_handle handle)
{
    if (IsHandleValid(handle) && IsHandleUsed(handle))
    {
        TList *obj = &list_pool_[handle];
        TListNode *cur_node = NULL;

        obj->is_used_ = False;

        for(TListNode *node = obj->list_head_.next_; node != &obj->list_head_; )
        {
            cur_node = node;
            node = node->next_;
            MyFree(cur_node->item_arr_);
            MyFree(cur_node);
        }

        obj->list_head_.prev_ = &obj->list_head_;
        obj->list_head_.next_ = &obj->list_head_;

        obj->item_cnt_ = 0;
    }
}

Int32 TListItemCount(TList_handle handle)
{
    Int32 ret = 0;

    if (IsHandleValid(handle) && IsHandleUsed(handle))
    {
        TList *obj = &list_pool_[handle];

        ret = obj->item_cnt_;
    }

    return ret;
}

Bool TListPush(TList_handle handle, void *new_item)
{
    Bool push_result = False;

    if (IsHandleValid(handle) && IsHandleUsed(handle))
    {
        TList *obj = &list_pool_[handle];
        TListNode *new_node = (TListNode *)MyMalloc(sizeof(TListNode));

        if (new_node != NULL)
        {
            new_node->item_arr_ = new_item;

            new_node->prev_ = obj->list_head_.prev_;
            new_node->next_ = &obj->list_head_;
            obj->list_head_.prev_->next_ = new_node;
            obj->list_head_.prev_ = new_node;

            obj->item_cnt_ ++;

            push_result = True;
        }
    }

    return push_result;
}

void* TListPeek(TList_handle handle)
{
    void *peek_item = NULL;

    if (IsHandleValid(handle) && IsHandleUsed(handle))
    {
        TList *obj = &list_pool_[handle];

        if (obj->item_cnt_ > 0)
        {
            peek_item = &obj->list_head_.next_->item_arr_;
        }
    }

    return peek_item;
}

void* TListPop(TList_handle handle)
{
    void *pop_item = NULL;

    if (IsHandleValid(handle) && IsHandleUsed(handle))
    {
        TList *obj = &list_pool_[handle];

        if (obj->item_cnt_ > 0)  // 有成员
        {
            TListNode *frist_node = obj->list_head_.next_;

            pop_item = frist_node->item_arr_;
            obj->item_cnt_ --;

            obj->list_head_.next_ = frist_node->next_;
            frist_node->next_->prev_ = &obj->list_head_;
            MyFree(frist_node);
        }
    }

    return pop_item;
}
